package com.xayy.mgt.service.impl;

import cn.kawins.base.result.CheckResult;
import cn.kawins.base.utils.BeanUtil;
import cn.kawins.base.utils.CollUtil;
import cn.kawins.mybatis.base.BaseServiceImpl;
import cn.kawins.mybatis.util.SnowflakeId;
import com.xayy.core.antlr4.utils.FunUtil;
import com.xayy.mgt.mapper.NodeInfoMapper;
import com.xayy.mgt.model.*;
import com.xayy.mgt.model.vo.HealthDeepVo;
import com.xayy.mgt.service.BridgeParamService;
import com.xayy.mgt.service.HealthDeepService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class HealthDeepServiceImpl extends BaseServiceImpl<HealthDeep> implements HealthDeepService {

    @Autowired
    private BridgeParamService bridgeParamService;

    @Autowired
    private NodeInfoMapper nodeInfoMapper;

    @Override
    @Transactional
    public CheckResult<Object> saveHealthDeep(HealthDeepVo healthDeepVo) {
        HealthDeep healthDeep = BeanUtil.copyBean(healthDeepVo, HealthDeep.class);
        CheckResult<?> checkName = checkName(false, healthDeep);
        if (checkName.no()) {
            return CheckResult.fail(checkName.getCheckMsg());
        }
        CheckResult<?> checkCode = checkCode(false, healthDeep);
        if (checkCode.no()) {
            return CheckResult.fail(checkCode.getCheckMsg());
        }
//        NodeTreeInfo nodeTreeInfo = nodeInfoMapper.selectByPrimaryKey(healthDeepVo.getNodeId());
//        NodeTreeInfo nodeTreeInfo = nodeInfoService.selectById(healthDeepVo.getNodeId());
//        CheckResult<?> checkSyntax = FunUtil.checkSyntax(nodeTreeInfo.getSatelliteId(), healthDeepVo.getNodeId(),
//                new Date(), healthDeepVo.getCustomParam());
//        if (checkSyntax.no()) {
//            return CheckResult.fail(checkSyntax.getCheckMsg());
//        }
        Long id = new SnowflakeId().genId("t_health_deep", "id");
        healthDeep.setId(id);
        this.insert(healthDeep);
        // 将健康度id和功能性信息中间表添加
        List<Long> functionIds = healthDeepVo.getFunctionIds();
        // 将健康度id和性能能性信息中间表添加
        List<Long> performanceIds = healthDeepVo.getPerformanceIds();
        List<BridgeParam> bridgeParams = new ArrayList<>();
        if (CollUtil.isNotEmpty(functionIds)) {
            functionIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(id);
                bridgeParam.setChildId(x);
                bridgeParam.setChildType(1);
                bridgeParam.setType(3);
                bridgeParams.add(bridgeParam);
            });
        }
        if (CollUtil.isNotEmpty(performanceIds)) {
            performanceIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(id);
                bridgeParam.setChildId(x);
                bridgeParam.setChildType(2);
                bridgeParam.setType(3);
                bridgeParams.add(bridgeParam);
            });
        }
        if (CollUtil.isNotEmpty(bridgeParams))
            bridgeParamService.insertList(bridgeParams);
        return CheckResult.success("新增成功");
    }

    @Override
    @Transactional
    public CheckResult<Object> updateHealthDeep(HealthDeepVo healthDeepVo) {
        HealthDeep healthDeep = BeanUtil.copyBean(healthDeepVo, HealthDeep.class);
        CheckResult<?> checkName = checkName(true, healthDeep);
        if (checkName.no()) {
            return CheckResult.fail(checkName.getCheckMsg());
        }
        CheckResult<?> checkCode = checkCode(true, healthDeep);
        if (checkCode.no()) {
            return CheckResult.fail(checkCode.getCheckMsg());
        }
//        NodeTreeInfo nodeTreeInfo = nodeInfoMapper.selectByPrimaryKey(healthDeepVo.getNodeId());
//        NodeTreeInfo nodeTreeInfo = nodeInfoService.selectById(healthDeepVo.getNodeId());
//        CheckResult<?> checkSyntax = FunUtil.checkSyntax(nodeTreeInfo.getSatelliteId(), healthDeepVo.getNodeId(),
//                new Date(), healthDeepVo.getCustomParam());
//        if (checkSyntax.no()) {
//            return CheckResult.fail(checkSyntax.getCheckMsg());
//        }
        this.updateById(healthDeep);
        // 将健康度id和功能性信息中间表添加
        List<Long> functionIds = healthDeepVo.getFunctionIds();
        // 将健康度id和性能能性信息中间表添加
        List<Long> performanceIds = healthDeepVo.getPerformanceIds();
        List<BridgeParam> bridgeParams = new ArrayList<>();
        if (CollUtil.isNotEmpty(functionIds)) {
            functionIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(healthDeep.getId());
                bridgeParam.setChildId(x);
                bridgeParam.setChildType(1);
                bridgeParam.setType(3);
                bridgeParams.add(bridgeParam);
            });
        }
        if (CollUtil.isNotEmpty(performanceIds)) {
            performanceIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(healthDeep.getId());
                bridgeParam.setChildId(x);
                bridgeParam.setChildType(2);
                bridgeParam.setType(3);
                bridgeParams.add(bridgeParam);
            });
        }
        bridgeParamService.delete(BridgeParam.builder().parentId(healthDeep.getId()).type(3).build());
        if (CollUtil.isNotEmpty(bridgeParams))
            bridgeParamService.insertList(bridgeParams);

        return CheckResult.success("修改成功");
    }

    @Override
    public CheckResult<HealthDeep> getHealthDeep(Long nodeId) {
        HealthDeep healthDeep = selectOne(HealthDeep.builder().nodeId(nodeId).build());
        return CheckResult.success(healthDeep);
    }

    @Override
    public HealthDeep getByNodeId(Long nodeId) {
        HealthDeep healthDeep = selectOne(HealthDeep.builder().nodeId(nodeId).build());
        return healthDeep;
    }

    @Override
    public CheckResult<HealthDeepVo> getHealthDeepVo(Long nodeId) {
        HealthDeep healthDeep = selectOne(HealthDeep.builder().nodeId(nodeId).build());
        if (BeanUtil.isNotEmpty(healthDeep)) {
            HealthDeepVo healthDeepVo = BeanUtil.copyBean(healthDeep, HealthDeepVo.class);
            List<BridgeParam> functions =
                    bridgeParamService.select(BridgeParam.builder().parentId(healthDeep.getId()).childType(1).build());
            List<BridgeParam> performances =
                    bridgeParamService.select(BridgeParam.builder().parentId(healthDeep.getId()).childType(2).build());
            List<Long> functionIds = functions.stream().map(BridgeParam::getChildId).collect(Collectors.toList());
            List<Long> performanceIds = performances.stream().map(BridgeParam::getChildId).collect(Collectors.toList());
            healthDeepVo.setFunctionIds(CollUtil.newArrayList(functionIds));
            healthDeepVo.setPerformanceIds(CollUtil.newArrayList(performanceIds));
            return CheckResult.success(healthDeepVo);
        }
        return CheckResult.success(new HealthDeepVo());
    }

    @Override
    @Transactional
    public CheckResult<Object> deleteByNodeId(Long id) {
        delete(HealthDeep.builder().nodeId(id).build());
        Example example = new Example(BridgeParam.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId", id);
        bridgeParamService.deleteByExample(example);
        return CheckResult.success("删除成功");
    }

    /**
     * 校验同节点下得健康度指标名称是否已存在
     *
     * @param isUpdate   是否更新
     * @param healthDeep 入参
     * @return 结果日志
     */
    private CheckResult<?> checkName(Boolean isUpdate, HealthDeep healthDeep) {
        Example example = new Example(FunctionalIndicators.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("nodeId", healthDeep.getNodeId());
        criteria.andEqualTo("metricsName", healthDeep.getMetricsName());
        if (Boolean.TRUE.equals(isUpdate)) {
            criteria.andNotEqualTo("id", healthDeep.getId());
        }
        int i = selectCountByExample(example);
        if (i > 0) {
            return CheckResult.fail("指标名称：" + healthDeep.getMetricsName() + "已经存在");
        }
        return CheckResult.success();
    }

    /**
     * 校验同节点下得健康度指标code是否已存在
     *
     * @param isUpdate   是否更新
     * @param healthDeep 入参
     * @return 结果日志
     */
    private CheckResult<?> checkCode(Boolean isUpdate, HealthDeep healthDeep) {
        Example example = new Example(AssociationParameter.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("nodeId", healthDeep.getNodeId());
        criteria.andEqualTo("metricsCode", healthDeep.getMetricsCode());
        if (Boolean.TRUE.equals(isUpdate)) {
            criteria.andNotEqualTo("id", healthDeep.getId());
        }
        int i = selectCountByExample(example);
        if (i > 0) {
            return CheckResult.fail("指标代号：" + healthDeep.getMetricsCode() + "已经存在");
        }
        return CheckResult.success();
    }

}
